#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <windows.h>

int count_chars(const char *filename)
{
    FILE *file = fopen(filename, "r");
    if (file == NULL)
    {
        printf("Error: File '%s' does not exist or cannot be opened\n", filename);
        return -1;
    }
    int count = 0;
    int c;
    while ((c = fgetc(file)) != EOF)
    {
        if (c != '\n') // Ignore newline characters
            count++;
        if (c == ' ')
        {
            count--;
        }
    }
    fclose(file);
    return count;
}

void count_chars_in_path(const char *path)
{
    char search_path[MAX_PATH];
    snprintf(search_path, MAX_PATH, "%s\\*.txt", path);

    WIN32_FIND_DATA findFileData;
    HANDLE hFind = FindFirstFile(search_path, &findFileData);

    if (hFind == INVALID_HANDLE_VALUE)
    {
        printf("No .txt files found in the specified path: %s\n", path);
        return;
    }

    do
    {
        char filepath[MAX_PATH];
        snprintf(filepath, MAX_PATH, "%s\\%s", path, findFileData.cFileName);
        int chars = count_chars(filepath);
        if (chars != -1)
        {
            printf("File: %s, Characters: %d\n", findFileData.cFileName, chars);
        }
    } while (FindNextFile(hFind, &findFileData) != 0);

    FindClose(hFind);
}

int count_words(const char *filename)
{
    FILE *file = fopen(filename, "r");
    if (file == NULL)
    {
        printf("Error: File '%s' does not exist or cannot be opened\n", filename);
        return -1;
    }
    int count = 0, in_word = 0;
    int c;
    while ((c = fgetc(file)) != EOF)
    {
        if (isspace(c)) // Ignore spaces and other whitespace characters
        {
            in_word = 0;
        }
        else if (isalnum(c) && !in_word) // Only count alphanumeric sequences as words
        {
            count++;
            in_word = 1;
        }
    }
    fclose(file);
    return count;
}

int count_sentences(const char *filename)
{
    FILE *file = fopen(filename, "r");
    if (file == NULL)
    {
        printf("Error: File '%s' does not exist or cannot be opened\n", filename);
        return -1;
    }
    int count = 0, last_was_end = 0;
    int c;
    while ((c = fgetc(file)) != EOF)
    {
        if (c == '.' || c == '!' || c == '?')
        {
            if (!last_was_end)
            {
                count++;
                last_was_end = 1;
            }
        }
        else
        {
            last_was_end = 0;
        }
    }
    fclose(file);
    return count;
}

int count_empty_lines(const char *filename)
{
    FILE *file = fopen(filename, "r");
    if (file == NULL)
    {
        printf("Error: File '%s' does not exist or cannot be opened\n", filename);
        return -1;
    }

    int count = 0;
    char line[1024];

    while (fgets(line, sizeof(line), file) != NULL)
    {
        int is_empty = 1;
        for (int i = 0; line[i] != '\0'; i++)
        {
            if (line[i] != ' ' && line[i] != '\t' && line[i] != '\n')
            {
                is_empty = 0;
                break;
            }
        }
        if (is_empty)
            count++;
    }

    fclose(file);
    return count;
}

int count_comment_lines(const char *filename)
{
    FILE *file = fopen(filename, "r");
    if (file == NULL)
    {
        printf("Error: File '%s' does not exist or cannot be opened\n", filename);
        return -1;
    }

    int count = 0;
    char line[1024];

    while (fgets(line, sizeof(line), file) != NULL)
    {
        int i = 0;
        while (line[i] == ' ' || line[i] == '\t')
        {
            i++;
        }
        if (strncmp(&line[i], "//", 2) == 0 || line[i] == '#')
        {
            count++;
        }
    }

    fclose(file);
    return count;
}

int count_code_lines(const char *filename)
{
    FILE *file = fopen(filename, "r");
    if (file == NULL)
    {
        printf("Error: File '%s' does not exist or cannot be opened\n", filename);
        return -1;
    }
    int total_lines = 0;
    int c;
    while ((c = fgetc(file)) != EOF)
    {
        if (c == '\n')
            total_lines++;
    }
    fclose(file);

    int empty_lines = count_empty_lines(filename);
    int comment_lines = count_comment_lines(filename);
    if (empty_lines == -1 || comment_lines == -1)
    {
        return -1;
    }

    int non_empty_lines = total_lines - empty_lines;
    return non_empty_lines - comment_lines;
}

int main(int argc, char *argv[])
{
    if (argc < 2)
    {
        printf("Usage: wc.exe [option]\n");
        printf("Supported options:\n");
        printf("  -c [filename]  Count characters in a specific file\n");
        printf("  -p [path]      Count characters in all .txt files in the specified path\n");
        printf("  -w  Count words\n");
        printf("  -s  Count sentences\n");
        printf("  -e  Count empty lines\n");
        printf("  -n  Count comment lines\n");
        printf("  -l  Count code lines\n");
        return 1;
    }

    char *option = argv[1];

    if (strcmp(option, "-c") == 0)
    {
        if (argc != 3)
        {
            printf("Error: Missing filename for -c option\n");
            return 1;
        }
        char *filename = argv[2];
        int chars = count_chars(filename);
        if (chars != -1)
            printf("Characters: %d\n", chars);
    }
    else if (strcmp(option, "-p") == 0)
    {
        if (argc != 3)
        {
            printf("Error: Missing path for -p option\n");
            return 1;
        }
        char *path = argv[2];
        count_chars_in_path(path);
    }
    else if (strcmp(option, "-w") == 0)
    {
        if (argc != 3)
        {
            printf("Error: Missing filename for -w option\n");
            return 1;
        }
        char *filename = argv[2];
        int words = count_words(filename);
        if (words != -1)
            printf("Word count: %d\n", words);
    }
    else if (strcmp(option, "-s") == 0)
    {
        if (argc != 3)
        {
            printf("Error: Missing filename for -s option\n");
            return 1;
        }
        char *filename = argv[2];
        int sentences = count_sentences(filename);
        if (sentences != -1)
            printf("Sentence count: %d\n", sentences);
    }
    else if (strcmp(option, "-e") == 0)
    {
        if (argc != 3)
        {
            printf("Error: Missing filename for -e option\n");
            return 1;
        }
        char *filename = argv[2];
        int empty = count_empty_lines(filename);
        if (empty != -1)
            printf("Empty line count: %d\n", empty);
    }
    else if (strcmp(option, "-n") == 0)
    {
        if (argc != 3)
        {
            printf("Error: Missing filename for -n option\n");
            return 1;
        }
        char *filename = argv[2];
        int comments = count_comment_lines(filename);
        if (comments != -1)
            printf("Comment line count: %d\n", comments);
    }
    else if (strcmp(option, "-l") == 0)
    {
        if (argc != 3)
        {
            printf("Error: Missing filename for -l option\n");
            return 1;
        }
        char *filename = argv[2];
        int code = count_code_lines(filename);
        if (code != -1)
            printf("Code line count: %d\n", code);
    }
    else
    {
        printf("Error: Unknown option '%s'\n", option);
        return 1;
    }

    return 0;
}
